﻿
using System;
using SqlSugar;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Options;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using Newtonsoft.Json;
using System.Text;
using PARK.Dependency;
using PARK.Common.Cache;
using PARK.Common.Const;
using System.Data;
using PARK.BussinCache.Interfaces;
using PARK.BussinCache.Entitys.Dto;
using PARK.BussinCache.Entitys.Entity;
using JNPF.Logging;
using PARK.Accessctl.Entitys;

namespace PARK.BussinCache.Repository
{
    /// <summary>
    /// 平台基础数据缓存
    /// </summary>
    public class ParkCacheRepository : IParkCacheRepository, ITransient
    {
        private readonly ICache _cache;
        private readonly CacheOptions _cacheOptions;
        private readonly HttpContext _httpContext;
        private readonly SqlSugarScope _db;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="cacheOptions"></param>
        /// <param name="resolveNamed"></param>
        public ParkCacheRepository(IOptions<CacheOptions> cacheOptions, Func<string, ISingleton, object> resolveNamed, ISqlSugarClient db)
        {
            _cacheOptions = cacheOptions.Value;
            _cache = resolveNamed(_cacheOptions.CacheType.ToString(), default) as ICache;
            _httpContext = App.HttpContext;
            _db = (SqlSugarScope)db;
        }

        #region 缓存功能方法
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        public async Task<long> RPushAsync(string key, object value)
        {
            return await _cache.RPush(key, value);
        }
        /// <summary>
        /// 从队列取值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public string LPopAsync(string key)
        {
            return _cache.LPopAsync(key);
        }
        /// <summary>
        /// 获取所有缓存关键字
        /// </summary>
        /// <returns></returns>
        [NonAction]
        public List<string> GetAllCacheKeys()
        {
            var cacheItems = _cache.GetAllKeys();
            if (cacheItems == null) return new List<string>();
            return cacheItems.Where(u => !u.ToString().StartsWith("mini-profiler")).Select(u => u).ToList();
        }
        /// <summary>
        /// 删除指定关键字缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public bool Del(string key)
        {
            _cache.Del(key);
            return true;
        }
        /// <summary>
        /// 删除指定关键字缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public Task<bool> DelAsync(string key)
        {
            _cache.DelAsync(key);
            return Task.FromResult(true);
        }
        /// <summary>
        /// 删除指定关键字数组缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public Task<bool> DelAsync(string[] key)
        {
            _cache.DelAsync(key);
            return Task.FromResult(true);
        }
        /// <summary>
        /// 删除某特征关键字缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public Task<bool> DelByPatternAsync(string key)
        {
            _cache.DelByPatternAsync(key);
            return Task.FromResult(true);
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        [NonAction]
        public bool Set(string key, object value)
        {
            return _cache.Set(key, value);
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="timeSpan">过期时间</param>
        /// <returns></returns>
        [NonAction]
        public bool Set(string key, object value, TimeSpan timeSpan)
        {
            return _cache.Set(key, value, timeSpan);
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <returns></returns>
        [NonAction]
        public async Task<bool> SetAsync(string key, object value)
        {
            return await _cache.SetAsync(key, value);
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <param name="value">值</param>
        /// <param name="timeSpan">过期时间</param>
        /// <returns></returns>
        [NonAction]
        public async Task<bool> SetAsync(string key, object value, TimeSpan timeSpan)
        {
            return await _cache.SetAsync(key, value, timeSpan);
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public string Get(string key)
        {
            return _cache.Get(key);
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public async Task<string> GetAsync(string key)
        {
            return await _cache.GetAsync(key);
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public T Get<T>(string key)
        {
            return _cache.Get<T>(key);
        }
        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">对象</typeparam>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public Task<T> GetAsync<T>(string key)
        {
            return _cache.GetAsync<T>(key);
        }
        /// <summary>
        /// 获取缓存过期时间
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public DateTime GetCacheOutTime(string key)
        {
            return _cache.GetCacheOutTime(key);
        }
        /// <summary>
        /// 检查给定 key 是否存在
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public bool Exists(string key)
        {
            return _cache.Exists(key);
        }
        /// <summary>
        /// 检查给定 key 是否存在
        /// </summary>
        /// <param name="key">键</param>
        /// <returns></returns>
        [NonAction]
        public Task<bool> ExistsAsync(string key)
        {
            return _cache.ExistsAsync(key);
        }
        /// <summary>
        /// 清空Redis缓存
        /// </summary>
        /// <returns></returns>
        [NonAction]
        public void ClearRedisCache()
        {
            _cache.ClearRedisCache();
        }
        #endregion

        #region 企业应用缓存
        /// <summary>
        /// 获取指定企业应用信息
        /// </summary>
        /// <returns></returns>
        [NonAction]
        public uniubiAppInfo GetCacheUniubiAppInfo(string CompanyId)
        {
            var cacheKey = CommonConst.CACHE_KEY_UniubiApp + CompanyId;
            var _output = Get<uniubiAppInfo>(cacheKey);
            if (_output == null)
            {
                StringBuilder dbSql = new StringBuilder("select a.F_Id,a.F_FullName,a.uni_appKey,a.uni_appSecret,a.uni_projectGuid,a.uni_token,a.uni_is from base_organize a where a.F_Id='" + CompanyId + "'");
                var _CpyTb = _db.SqlQueryable<DataTable>(dbSql.ToString()).ToDataTable();
                if (_CpyTb != null && _CpyTb.Rows.Count > 0)
                {
                    _output = new uniubiAppInfo()
                    {
                        CompanyId = CompanyId,
                        CompanyName = _CpyTb.Rows[0]["F_FullName"].ToString(),
                        uni_is = !string.IsNullOrEmpty(_CpyTb.Rows[0]["uni_is"].ToString()) ? int.Parse(_CpyTb.Rows[0]["uni_is"].ToString()) : 0,
                        uni_appKey = _CpyTb.Rows[0]["uni_appKey"].ToString(),
                        uni_appSecret = _CpyTb.Rows[0]["uni_appSecret"].ToString(),
                        uni_projectGuid = _CpyTb.Rows[0]["uni_projectGuid"].ToString(),
                        uni_token = _CpyTb.Rows[0]["uni_token"].ToString(),
                        uni_tokenLastTime = DateTime.Now.AddDays(-1)
                    };
                    //更新学生缓存
                    SetUniubiAppInfoCache(_output);
                }
            }
            return _output;
        }
        /// <summary>
        /// 保存企业应用信息到缓存
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [NonAction]
        public bool SetUniubiAppInfoCache(uniubiAppInfo input)
        {
            var cacheKey = CommonConst.CACHE_KEY_UniubiApp + input.CompanyId;
            Del(cacheKey);
            return Set(cacheKey, input);
        }
        #endregion

        #region 宇泛门禁人脸识别事件处理
        /// <summary>
        /// 加入待处理队列
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<long> SetEvt101004queue(UniEvt101004Entity Input)
        {
            var cacheKey = CommonConst.CACHE_KEY_UniEvt101004;
            return await RPushAsync(cacheKey, Input);
        }
        /// <summary>
        /// 获取待解析事件
        /// </summary>
        /// <returns></returns>
        [NonAction]
        public string GetEvt101004queueList()
        {
            var cacheKey = CommonConst.CACHE_KEY_UniEvt101004;
            return LPopAsync(cacheKey);
        }
        #endregion

        #region 宇泛设备权限处理
        /// <summary>
        /// 加入待处理队列
        /// </summary>
        /// <param name="Input"></param>
        /// <returns></returns>
        [NonAction]
        public async Task<long> SetAccAuthqueue(List<AccessCtlauthTaskEntity> Input)
        {
            var cacheKey = CommonConst.CACHE_KEY_CtlauthTask;
            return await RPushAsync(cacheKey, Input);
        }
        /// <summary>
        /// 获取待处理设备权限事件
        /// </summary>
        /// <returns></returns>
        [NonAction]
        public string GetAccAuthqueueList()
        {
            var cacheKey = CommonConst.CACHE_KEY_CtlauthTask;
            return LPopAsync(cacheKey);
        }
        #endregion
    }
}
